package org.easy.core.util;

import org.easy.core.context.SecurityContextHolder;
import org.easy.core.dto.RequestSummary;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.core.io.InputStreamSource;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class RequestUtil {

    public static RequestSummary getRequestSummary(HttpServletRequest request, ProceedingJoinPoint proceedingJoinPoint) {
        String url;
        try {
            url = request.getRequestURL().toString();
        } catch (IllegalStateException e) {
            System.out.println("单元测试环境无法取得httpServletRequest 默认返回跳过切面");
            e.printStackTrace();
            return null;
        }
        String method = request.getMethod();
        String token = request.getHeader("token");

        String heads = getHead();

        List<Object> args = filterArgs(proceedingJoinPoint.getArgs());
        return new RequestSummary(IpUtil.getIpAddr(request), url, method, heads, token, args);
    }

    private static String getHead() {
        StringBuffer heads = new StringBuffer();
        heads.append("location:").append(SecurityContextHolder.getLocation());
        heads.append(" ");
        heads.append("client:").append(SecurityContextHolder.getClient());
        heads.append(" ");
        heads.append("userId:").append(SecurityContextHolder.getUserId());
        return heads.toString();
    }

    private static List<Object> filterArgs(Object[] args) {
        List<Object> objects = new ArrayList<>();
        for (Object arg : args) {
            if (arg instanceof OutputStream ||
                    arg instanceof InputStream ||
                    arg instanceof ServletRequest ||
                    arg instanceof ServletResponse ||
                    arg instanceof InputStreamSource[] ||
                    arg instanceof InputStreamSource
            ) {
                continue;
            }
            objects.add(arg);
        }
        return objects;
    }
}
